package p2p

import (
	"context"
	"feishup2pclient/data"
	"feishup2pclient/msg"
	"fmt"
	"sync"
	"time"

	"github.com/libp2p/go-libp2p-core/host"
	"github.com/libp2p/go-libp2p-core/network"
	"github.com/libp2p/go-libp2p-core/peer"
	dht "github.com/libp2p/go-libp2p-kad-dht"
)

var FailsCh chan []data.P2PPeerInfo = make(chan []data.P2PPeerInfo, 20)

// Discover启动一个基于DHT的发现系统，查找并添加具有相同会合字符串的节点。
func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, peerTable *sync.Map) {

	for {
		fails := make([]data.P2PPeerInfo, 0)

		peerTable.Range(func(key, value interface{}) bool {
			id, ok := value.(peer.ID)
			if ok {

				if h.Network().Connectedness(id) != network.Connected {

					// dht 查找节点

					_ctx, _ := context.WithTimeout(ctx, 5*time.Second)
					addrinfo, err1 := dht.FindPeer(_ctx, id)
					if err1 != nil {
						// dht查找失败设备未上线
						msg.SendMessage("查找失败设备未上线, %s", addrinfo)
						updateLocalPeerStatus(id, h, 3)
						return true
					}
					_, err2 := h.Network().DialPeer(ctx, id)
					if err2 != nil {
						updateLocalPeerStatus(id, h, 3)
						return true
					}
				} else {
					updateLocalPeerStatus(id, h, 2)
				}

			}

			return true
		})
		if len(fails) > 0 {
			FailsCh <- fails
		}
	}
}

func updateLocalPeerStatus(id peer.ID, h host.Host, status int) {
	data.LocalPeers.Range(func(key, value any) bool {
		cid := key.(string)
		localPeer := value.(*data.LocalPeer)
		if localPeer.LibP2PId == id.Pretty() {
			mode := "p2p"
			for _, v := range h.Network().ConnsToPeer(id) {
				msg.SendMessage(fmt.Sprintf("[%s]: %s", localPeer.LibP2PId, v.RemoteMultiaddr()))
				if isRelayAddress(v.RemoteMultiaddr()) {
					mode = "relay"
				}
			}
			localPeer.Mode = mode
			localPeer.Status = status
			data.LocalPeers.Store(cid, localPeer)
			return false
		}
		return true
	})
}
